package com.bizzan.bitrade.listenConfig;

import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.listener.Event;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.listener.NamingEvent;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Component
public class NacosInstanceEventListener {
//
//    @Resource
//    private NamingService namingService;

    @Autowired
    private NamingService namingService;  // 使用 @Autowired 注入

    private Map<String, List<Instance>> serviceInstanceCache = new ConcurrentHashMap<>();

    /**
     * 初始化订阅
     */
    @PostConstruct
    public void init() {
        // 订阅需要监听的服务
        String[] servicesToWatch = {"cloud-service","admin-service","exchange-service","user-service", "order-service", "product-service"};

        for (String serviceName : servicesToWatch) {
            try {
                subscribeService(serviceName);
            } catch (Exception e) {
                System.err.println("订阅服务失败: " + serviceName + ", 错误: " + e.getMessage());
            }
        }
    }

    /**
     * 订阅指定服务的实例变化
     */
    private void subscribeService(String serviceName) throws Exception {
        // 订阅服务变化
        namingService.subscribe(serviceName, new EventListener() {
            @Override
            public void onEvent(Event event) {
                if (event instanceof NamingEvent) {
                    handleNamingEvent((NamingEvent) event);
                }
            }
        });

        // 初始化缓存
        List<Instance> instances = namingService.getAllInstances(serviceName);
        serviceInstanceCache.put(serviceName, new ArrayList<>(instances)); // Java 8 兼容

        System.out.println("已订阅服务: " + serviceName + ", 当前实例数: " + instances.size());
    }

    /**
     * 处理服务实例变化事件
     */
    private void handleNamingEvent(NamingEvent event) {
        String serviceName = event.getServiceName();
        List<Instance> currentInstances = event.getInstances();

        // Java 8 兼容的方式获取之前的实例
        List<Instance> previousInstances = serviceInstanceCache.get(serviceName);
        if (previousInstances == null) {
            previousInstances = new ArrayList<>(); // 使用空列表而不是 List.of()
        }

        // 检测注销的实例
        List<Instance> canceledInstances = findCanceledInstances(previousInstances, currentInstances);

        // 处理每个注销的实例
        for (Instance canceledInstance : canceledInstances) {
            handleInstanceCanceled(serviceName, canceledInstance);
        }

        // 检测新注册的实例
        List<Instance> newInstances = findNewInstances(previousInstances, currentInstances);
        for (Instance newInstance : newInstances) {
            handleInstanceRegistered(serviceName, newInstance);
        }

        // 更新缓存 - 创建新的 ArrayList 避免引用问题
        serviceInstanceCache.put(serviceName, new ArrayList<>(currentInstances));

        System.out.println("服务实例变化: " + serviceName +
                ", 之前: " + previousInstances.size() +
                ", 现在: " + currentInstances.size() +
                ", 注销: " + canceledInstances.size() +
                ", 新增: " + newInstances.size());
    }

    /**
     * 找出注销的实例
     */
    private List<Instance> findCanceledInstances(List<Instance> previous, List<Instance> current) {
        return previous.stream()
                .filter(prev -> current.stream()
                        .noneMatch(curr -> isSameInstance(prev, curr)))
                .collect(Collectors.toList());
    }

    /**
     * 找出新注册的实例
     */
    private List<Instance> findNewInstances(List<Instance> previous, List<Instance> current) {
        return current.stream()
                .filter(curr -> previous.stream()
                        .noneMatch(prev -> isSameInstance(prev, curr)))
                .collect(Collectors.toList());
    }

    /**
     * 判断是否为同一个实例
     */
    private boolean isSameInstance(Instance instance1, Instance instance2) {
        return instance1.getIp().equals(instance2.getIp()) &&
                instance1.getPort() == instance2.getPort();
    }

    /**
     * 处理实例注销事件 - 替换 EurekaInstanceCanceledEvent
     */
    private void handleInstanceCanceled(String serviceName, Instance canceledInstance) {
        String instanceId = canceledInstance.getIp() + ":" + canceledInstance.getPort();

        System.out.println("🛑 服务实例注销: " + serviceName + " - " + instanceId);

        // 这里放置原来 EurekaInstanceCanceledEvent 中的业务逻辑
        cleanLocalCache(serviceName, instanceId);
        updateLoadBalancer(serviceName, canceledInstance);
        sendCanceledNotification(serviceName, canceledInstance);
        logInstanceCanceled(serviceName, canceledInstance);
    }

    /**
     * 处理实例注册事件
     */
    private void handleInstanceRegistered(String serviceName, Instance newInstance) {
        String instanceId = newInstance.getIp() + ":" + newInstance.getPort();
        System.out.println("✅ 服务实例注册: " + serviceName + " - " + instanceId);
    }

    // ========== 业务方法 ==========

    private void cleanLocalCache(String serviceName, String instanceId) {
        System.out.println("清理本地缓存: " + serviceName + " - " + instanceId);
        // 实现你的缓存清理逻辑
    }

    private void updateLoadBalancer(String serviceName, Instance instance) {
        System.out.println("更新负载均衡器: " + serviceName);
        // 实现你的负载均衡更新逻辑
    }

    private void sendCanceledNotification(String serviceName, Instance instance) {
        System.out.println("发送实例注销通知: " + serviceName);
        // 实现你的通知逻辑
    }

    private void logInstanceCanceled(String serviceName, Instance instance) {
        System.out.println("记录实例注销日志: " + serviceName +
                " - " + instance.getIp() + ":" + instance.getPort());
        // 实现你的日志记录逻辑
    }
}